package com.winning.devops.demo.controller;

import com.fasterxml.jackson.annotation.JsonView;
import com.winning.devops.demo.exception.UserNotExistsException;
import com.winning.devops.demo.model.QueryCondition;
import com.winning.devops.demo.model.User;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author chensj
 * @title User RestAPI Controller
 * @project winning-spring-security
 * @package com.winning.devops.demo.controller
 * @date: 2019-05-09 22:12
 */
@RestController
@RequestMapping(value = "/user")
public class UserController {

    /**logger*/
    private static final Logger logger = LoggerFactory.getLogger(UserController.class);

    /**
     *  用户查询的类
     * @{code (@RequestParam} 指定请求中必须携带一个username的参数，否则报错，返回错误码400
     *    属性说明：
     *      required:
     *          如果不是需要的，则可以设置required为false，默认为true
     *      name/value:
     *          name与value的参数意义是一样的，用法一直
     *          传入参数，与书写参数名称不一致的时候使用
     *          当传入参数为nickname，而接口使用参数为username，那么就可以这样设置
     *          {@code @RequestParam(name="nickname")} 表示username获取的值是nickname提供的
     *     defaultValue：
     *           参数如果没有传入，用来指定默认值
     * @return
     */
    @GetMapping("/list")
    @JsonView(User.UserSimpleView.class)
    public List<User> user(QueryCondition condition, @PageableDefault() Pageable pageable){
        // 通过反射方法将对象打印出来
        logger.info("QueryCondition:{}", ReflectionToStringBuilder.toString(condition, ToStringStyle.MULTI_LINE_STYLE));
        logger.info("Pageable:{}", ReflectionToStringBuilder.toString(pageable, ToStringStyle.MULTI_LINE_STYLE));
        List<User> users = new ArrayList();
        users.add(new User(1L,"aa","123456",new Date()));
        users.add(new User(2L,"bb","123456",new Date()));
        users.add(new User(3L,"cc","123456",new Date()));
        return users;
    }

    /**
     *  :\\d+ 为正则表达式，限制当前的传入的ID只能是数字
     * @param id
     * @return
     */
    @GetMapping(value = "/{id:\\d+}")
    @JsonView(User.UserDetailView.class)
    public User info(@PathVariable Long id ){
        // 测试 spring boot 的错误处理
//        throw  new RuntimeException("user not exists");
        throw new UserNotExistsException(id+"");
//        System.out.println(id);
//        User user = new User();
//        user.setId(id);
//        user.setName("tom");
//        user.setPassword("123456");
//        return user;
    }

    /**
     * 用户新增接口
     * @param user
     * @return
     */
    @PostMapping
    public User add(@Valid @RequestBody User user, BindingResult errors){

        if(errors.hasErrors()){
            // must not be blank
            errors.getAllErrors().stream().forEach(item -> System.out.println(item.getDefaultMessage()));
        }
        System.out.println(ReflectionToStringBuilder.toString(user, ToStringStyle.MULTI_LINE_STYLE));
        user.setId(1L);
        return user;
    }

    @PutMapping("{id:\\d+}")
    public User update(@Valid @RequestBody User user, BindingResult errors){
        if(errors.hasErrors()){
            // must not be blank
            errors.getAllErrors().stream().forEach(error -> {
                FieldError fieldError = (FieldError) error;
                // 获取字段信息和错误信息
                logger.info("Field:{},Error Message：{}",fieldError.getField(),fieldError.getDefaultMessage());
            });
        }
        System.out.println(ReflectionToStringBuilder.toString(user, ToStringStyle.MULTI_LINE_STYLE));
        return user;
    }

    /**
     * 用户删除的方法
     * @param id
     */
    @DeleteMapping("{id:\\d+}")
    public void delete(@PathVariable String id){
        System.out.println(id);
    }
}
